/**********************************************************************
 *** *                                                            * ***
 *** *  Copyright (c) 2013 Harmonia Holdings Group LLC            * ***
 *** *                                                            * ***
 *** * Permission is hereby granted to use, modify, copy, and     * ***
 *** * distribute this software and its documentation for any     * ***
 *** * purpose only without profit, provided that the above       * ***
 *** * Copyright Notice appears in all copies and that both the   * ***
 *** * Copyright Notice and this Permission Notice appears in     * ***
 *** * every copy of supporting documentation.  No title to nor   * ***
 *** * ownership of the software is transferred hereby.  The name * ***
 *** * of Harmonia Holdings Group LLC shall not be used in        * ***
 *** * advertising or publicity related to the distribution of    * ***
 *** * the software without specific, written, prior permission.  * ***
 *** * This software is provided as-delivered without expressed   * ***
 *** * or implied warranty.  Harmonia Holdings Group LLC          * ***
 *** * makes no representation about the suitability of this      * ***
 *** * software for any purpose and accepts no responsibility for * ***
 *** * its use.                                                   * ***
 *** *                                                            * ***
 *** ************************************************************** ***
 *** *                                                            * ***
 *** * This program is free software; you can redistribute it     * ***
 *** * and/or modify it under the terms of the GNU General Public * ***
 *** * License as published by the Free Software Foundation;      * ***
 *** * either version 2 of the License, or (at your option) any   * ***
 *** * later version.                                             * ***
 *** *                                                            * ***
 *** * This program is distributed in the hope that it will be    * ***
 *** * useful, but WITHOUT ANY WARRANTY; without even the implied * ***
 *** * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR    * ***
 *** * PURPOSE.  See the GNU General Public License for more      * ***
 *** * details.                                                   * ***
 *** *                                                            * ***
 *** * You should have received a copy of the GNU General Public  * ***
 *** * License along with this program; if not, write to the Free * ***
 *** * Software Foundation, Inc., 51 Franklin Street, Fifth       * ***
 *** * Floor, Boston, MA 02110-1301, USA.                         * ***
 *** *                                                            * ***
 *** * For more information: http://www.gnu.org/licenses/gpl.html * ***
 *** *                                                            * ***
 **********************************************************************/
package org.etexascode.interrep.datamodel;

public class VehicleInjectionCommand extends VehicleCommand {
	/** Serial ID */
	private static final long serialVersionUID = 498144725076505579L;
	
	// NOTE: Documented defaults/constraints are specifically for TEXAS.
	
	/**
	 * The exact time the vehicle enters the queue. Should be between the previous simTime and the current simTime.
	 */
	private double queue_in_time;
	
	/**
	 * Vehicle type. The Vehicle.VEHICLE_TYPE enum should have the correct values.
	 */
	private Vehicle.VEHICLE_TYPE vehicle_class_number;
	
	// TODO: janway - what is this.
	private int driver_class_number = 1;
	
	/**
	 * The preferred speed for this vehicle, in meters per second.
	 */
	private double desired_speed;
	
	/**
	 * The preferred outbound approach for this vehicle.
	 */
	private int desired_outbound_approach;
	
	/**
	 * The approach the vehicle enters in.
	 */
	private int inbound_approach;
	
	/**
	 * The lane the vehicle enters in.
	 */
	private int inbound_lane_number;
	
	/**
	 * Whether the simulator should print information when a vehicle logs out.
	 */
	private boolean print_logout_stats = false;
	
	/**
	 * Whether the vehicle should try to use the free U-turn lane at a diamond interchange. 0 = no, 1 = yes.
	 */
	private boolean use_U_turn = false;
	
	// TODO: janway - should find out and document what these do. Using default values provided by Tom for now.
	private double forced_stop_time = 0; // seconds. 0 -> no forced stop.
	private int forced_stop_link_number = 0; 
	private double forced_stop_position = 0.0; // ft
	private double forced_stop_dwell_time = 0.0; // seconds
	private double forced_go_time = 0; // seconds. 0 -> no forced go.
	private double forced_go_active_time = 0.0; // seconds
	private double forced_run_red_time = 0; // seconds. 0 -> no forced run red.
	private double forced_run_red_active_time = 0.0; // seconds
	
	/**
	 * Is this vehicle an emergency vehicle?
	 */
	private boolean emergency_vehicle = false;
	
	/**
	 * The speed of the vehicle when it enters, in meters per second.
	 */
	private double initial_speed;
	
	/**
	 * The acceleration of the vehicle when it enters, in meters per second^2.
	 */
	private double initial_acceleration;
	
	/**
	 * The jerk rate of the vehicle when it enters, in meters per second^3.
	 */
	private double initial_jerk = 0.0;
	
	/**
	 * Default constructor - needed for serialization.
	 */
	public VehicleInjectionCommand() {}
	
	/**
	 * Takes in the required parameters.
	 * @param queue_in_time The queue in time.
	 * @param type The vehicle type.
	 * @param desired_speed The desired speed.
	 * @param desired_outbound_approach The desired outbound approach.
	 * @param inbound_approach The inbound approach.
	 * @param inbound_lane_number The inbound lane number.
	 * @param vehicle_number The vehicle id number. Should be non-negative and unique for the simulation.
	 * @param initial_speed The initial speed.
	 * @param initial_acceleration The initial acceleration.
	 */
	public VehicleInjectionCommand(double queue_in_time, Vehicle.VEHICLE_TYPE type, double desired_speed, int desired_outbound_approach,
			int inbound_approach, int inbound_lane_number, int vehicle_number, double initial_speed, double initial_acceleration) {
		super(vehicle_number, 0); // sets vehicle id and puts in a dummy command value.
		this.queue_in_time = queue_in_time;
		this.vehicle_class_number = type;
		this.desired_speed = desired_speed;
		this.desired_outbound_approach = desired_outbound_approach;
		this.inbound_approach = inbound_approach;
		this.inbound_lane_number = inbound_lane_number;
		this.initial_speed = initial_speed;
		this.initial_acceleration = initial_acceleration;
	}

	/**
	 * @return the queue_in_time
	 */
	public double getQueue_in_time() {
		return queue_in_time;
	}

	/**
	 * @param queue_in_time the queue_in_time to set
	 */
	public void setQueue_in_time(double queue_in_time) {
		this.queue_in_time = queue_in_time;
	}

	/**
	 * @return the vehicle_class_number
	 */
	public Vehicle.VEHICLE_TYPE getVehicle_class_number() {
		return vehicle_class_number;
	}

	/**
	 * @param vehicle_class_number the vehicle_class_number to set
	 */
	public void setVehicle_class_number(Vehicle.VEHICLE_TYPE vehicle_class_number) {
		this.vehicle_class_number = vehicle_class_number;
	}

	/**
	 * @return the driver_class_number
	 */
	public int getDriver_class_number() {
		return driver_class_number;
	}

	/**
	 * @param driver_class_number the driver_class_number to set
	 */
	public void setDriver_class_number(int driver_class_number) {
		this.driver_class_number = driver_class_number;
	}

	/**
	 * @return the desired_speed
	 */
	public double getDesired_speed() {
		return desired_speed;
	}

	/**
	 * @param desired_speed the desired_speed to set
	 */
	public void setDesired_speed(double desired_speed) {
		this.desired_speed = desired_speed;
	}

	/**
	 * @return the desired_outbound_approach
	 */
	public int getDesired_outbound_approach() {
		return desired_outbound_approach;
	}

	/**
	 * @param desired_outbound_approach the desired_outbound_approach to set
	 */
	public void setDesired_outbound_approach(int desired_outbound_approach) {
		this.desired_outbound_approach = desired_outbound_approach;
	}

	/**
	 * @return the inbound_approach
	 */
	public int getInbound_approach() {
		return inbound_approach;
	}

	/**
	 * @param inbound_approach the inbound_approach to set
	 */
	public void setInbound_approach(int inbound_approach) {
		this.inbound_approach = inbound_approach;
	}

	/**
	 * @return the inbound_lane_number
	 */
	public int getInbound_lane_number() {
		return inbound_lane_number;
	}

	/**
	 * @param inbound_lane_number the inbound_lane_number to set
	 */
	public void setInbound_lane_number(int inbound_lane_number) {
		this.inbound_lane_number = inbound_lane_number;
	}

	/**
	 * @return the print_logout_stats
	 */
	public boolean getPrint_logout_stats() {
		return print_logout_stats;
	}

	/**
	 * @param print_logout_stats the print_logout_stats to set
	 */
	public void setPrint_logout_stats(boolean print_logout_stats) {
		this.print_logout_stats = print_logout_stats;
	}

	/**
	 * @return the use_U_turn
	 */
	public boolean getUse_U_turn() {
		return use_U_turn;
	}

	/**
	 * @param use_U_turn the use_U_turn to set
	 */
	public void setUse_U_turn(boolean use_U_turn) {
		this.use_U_turn = use_U_turn;
	}

	/**
	 * @return the forced_stop_time
	 */
	public double getForced_stop_time() {
		return forced_stop_time;
	}

	/**
	 * @param forced_stop_time the forced_stop_time to set
	 */
	public void setForced_stop_time(double forced_stop_time) {
		this.forced_stop_time = forced_stop_time;
	}

	/**
	 * @return the forced_stop_link_number
	 */
	public int getForced_stop_link_number() {
		return forced_stop_link_number;
	}

	/**
	 * @param forced_stop_link_number the forced_stop_link_number to set
	 */
	public void setForced_stop_link_number(int forced_stop_link_number) {
		this.forced_stop_link_number = forced_stop_link_number;
	}

	/**
	 * @return the forced_stop_position
	 */
	public double getForced_stop_position() {
		return forced_stop_position;
	}

	/**
	 * @param forced_stop_position the forced_stop_position to set
	 */
	public void setForced_stop_position(double forced_stop_position) {
		this.forced_stop_position = forced_stop_position;
	}

	/**
	 * @return the forced_stop_dwell_time
	 */
	public double getForced_stop_dwell_time() {
		return forced_stop_dwell_time;
	}

	/**
	 * @param forced_stop_dwell_time the forced_stop_dwell_time to set
	 */
	public void setForced_stop_dwell_time(double forced_stop_dwell_time) {
		this.forced_stop_dwell_time = forced_stop_dwell_time;
	}

	/**
	 * @return the forced_go_time
	 */
	public double getForced_go_time() {
		return forced_go_time;
	}

	/**
	 * @param forced_go_time the forced_go_time to set
	 */
	public void setForced_go_time(double forced_go_time) {
		this.forced_go_time = forced_go_time;
	}

	/**
	 * @return the forced_go_active_time
	 */
	public double getForced_go_active_time() {
		return forced_go_active_time;
	}

	/**
	 * @param forced_go_active_time the forced_go_active_time to set
	 */
	public void setForced_go_active_time(double forced_go_active_time) {
		this.forced_go_active_time = forced_go_active_time;
	}

	/**
	 * @return the forced_run_red_time
	 */
	public double getForced_run_red_time() {
		return forced_run_red_time;
	}

	/**
	 * @param forced_run_red_time the forced_run_red_time to set
	 */
	public void setForced_run_red_time(double forced_run_red_time) {
		this.forced_run_red_time = forced_run_red_time;
	}

	/**
	 * @return the forced_run_red_active_time
	 */
	public double getForced_run_red_active_time() {
		return forced_run_red_active_time;
	}

	/**
	 * @param forced_run_red_active_time the forced_run_red_active_time to set
	 */
	public void setForced_run_red_active_time(double forced_run_red_active_time) {
		this.forced_run_red_active_time = forced_run_red_active_time;
	}

	/**
	 * @return the emergency_vehicle
	 */
	public boolean getEmergency_vehicle() {
		return emergency_vehicle;
	}

	/**
	 * @param emergency_vehicle the emergency_vehicle to set
	 */
	public void setEmergency_vehicle(boolean emergency_vehicle) {
		this.emergency_vehicle = emergency_vehicle;
	}

	/**
	 * @return the initial_speed
	 */
	public double getInitial_speed() {
		return initial_speed;
	}

	/**
	 * @param initial_speed the initial_speed to set
	 */
	public void setInitial_speed(double initial_speed) {
		this.initial_speed = initial_speed;
	}

	/**
	 * @return the initial_acceleration
	 */
	public double getInitial_acceleration() {
		return initial_acceleration;
	}

	/**
	 * @param initial_acceleration the initial_acceleration to set
	 */
	public void setInitial_acceleration(double initial_acceleration) {
		this.initial_acceleration = initial_acceleration;
	}

	/**
	 * @return the initial_jerk
	 */
	public double getInitial_jerk() {
		return initial_jerk;
	}

	/**
	 * @param initial_jerk the initial_jerk to set
	 */
	public void setInitial_jerk(double initial_jerk) {
		this.initial_jerk = initial_jerk;
	}
}
